/**
 * Copyright &copy; 2013-2015 山东易科德软件有限公司 All rights reserved.
 */
package cn.net.ecode.modules.sys.entity;

import java.util.Date;
import java.util.List;

import javax.validation.constraints.Pattern;

import org.apache.commons.lang3.BooleanUtils;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;

import cn.net.ecode.common.config.Global;
import cn.net.ecode.common.persistence.DataEntity;
import cn.net.ecode.common.persistence.annotation.Id;
import cn.net.ecode.common.utils.StringUtils;
import cn.net.ecode.common.utils.excel.annotation.ExcelField;
import cn.net.ecode.common.utils.excel.fieldtype.RoleListType;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.Lists;

/**
 * 用户Entity
 * @author ThinkGem
 * @version 2014-8-19
 */
public class User extends DataEntity<User> {

	private static final long serialVersionUID = 1L;
	private String userCode;	// 登录账号（唯一编码）
	private String loginCode;	// 登录账号（集团内唯一）
	private String password;	// 登录密码
	private String userName;	// 昵称
	private String email;		// 邮箱
	private String mobile;		// 手机
	private String phone;		// 电话
//	private String weixin;		// 微信号
//	private String qq;			// QQ号
	private String photo;		// 头像
	private String imei;		// 手机串号
	private String userType;	// 用户类型（1员工 2会员 3往来单位）
	private String refCode;		// 用户类型引用编号
	private String refName;		// 用户类型引用姓名
	private String pwdQuestion;			// 密保问题
	private String pwdQuestionAnswer;	// 密保问题答案
	private String pwdQuestion2;		// 密保问题2
	private String pwdQuestionAnswer2;	// 密保问题答案2
	private String pwdQuestion3;		// 密保问题3
	private String pwdQuestionAnswer3;	// 密保问题答案3
	private Date pwdModifyDate;	// 密码修改时间
	private String mgrType;		// 管理员类型（0非管理员 1二级管理员 2集团管理员）
	private String loginIp;		// 最后登陆IP
	private Date loginDate;		// 最后登陆时间
	private Date freezeDate;	// 冻结时间
	private String extendS1;	// 扩展字段String1
	private String extendS2;	// 扩展字段String2
	private String extendS3;	// 扩展字段String3
	private String extendS4;	// 扩展字段String4
	private String extendS5;	// 扩展字段String5
	private Long extendI1;		// 扩展字段Integer1
	private Long extendI2;		// 扩展字段Integer2
	private Long extendI3;		// 扩展字段Integer3
	private Float extendF1;		// 扩展字段Float1
	private Float extendF2;		// 扩展字段Float2
	private Float extendF3;		// 扩展字段Float3
	private Date extendD1;		// 扩展字段Date1
	private Date extendD2;		// 扩展字段Date2
	private Date extendD3;		// 扩展字段Date3
	
	private boolean isAll;	// 查询条件：是否过滤数据控制权限 true 查询所有，false 过滤
	
//	private String oldUserCode;	// 原登录名
//	private String newPassword;	// 新密码
	
	private String oldLoginIp;	// 上次登陆IP
	private Date oldLoginDate;	// 上次登陆日期
	
	private String roleCode;	// 根据角色查询用户条件
	
	private List<Role> roleList = Lists.newArrayList(); // 拥有角色列表
	private List<UserDataScope> userDataScopeList = Lists.newArrayList(); // 拥有数据权限列表

	private String roleCodes;	//角色ID
	private String companyCodes;//公司的ID
	private String officeCodes;	//组织机构ID
	
	private Object refObj;		// 用户类型引用数据对象（扩展类型对应数据）
	private Employee employee;	//员工信息
	
	
	private String officeCode;
	private String officeName;

	@Deprecated // 不用了
	private List<String> scriptSessionIds = Lists.newArrayList(); // 当前用户登录脚本会话ID
	
	public User() {
		super();
		this.userType = USER_TYPE_EMPLOYEE;
		this.mgrType = MGR_TYPE_NOT_ADMIN;
	}
	
	public User(String id){
		super(id);
		this.userType = USER_TYPE_EMPLOYEE;
		this.mgrType = MGR_TYPE_NOT_ADMIN;
	}

	public User(Role role){
		this();
		if (role.getRoleCode() != null){
			this.roleCode = role.getRoleCode();
		}
	}
	
	@ExcelField(title="ID", type=1, align=2, sort=1)
	public String getId() {
		return super.getId();
	}
	
	@Id
	@ExcelField(title="登录名", align=2, sort=30)
	public String getUserCode() {
		return userCode;
	}

	public void setUserCode(String userCode) {
		this.userCode = userCode;
	}

	@Pattern(regexp="[a-zA-Z0-9_]{0,30}", message="登录编码长度不能大于 30 个字符，并且只能包含字母、数字、下划线")
	public String getLoginCode() {
		return loginCode;
	}

	public void setLoginCode(String loginCode) {
		this.loginCode = loginCode;
	}

	@JsonIgnore
	@Length(min=0, max=100, message="密码长度不能超过 100 个字符")
	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
	
	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	@Email(message="邮箱格式不正确")
	@Length(min=0, max=200, message="邮箱长度不能超过 200 个字符")
	@ExcelField(title="邮箱", align=1, sort=50)
	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}
	
	@Length(min=0, max=200, message="电话长度不能超过 200 个字符")
	@ExcelField(title="电话", align=2, sort=60)
	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	@Length(min=0, max=200, message="手机长度不能超过 200 个字符")
	@ExcelField(title="手机", align=2, sort=70)
	public String getMobile() {
		return mobile;
	}

	public void setMobile(String mobile) {
		this.mobile = mobile;
	}

	public String getImei() {
		return imei;
	}

	public void setImei(String imei) {
		this.imei = imei;
	}

	public String getPhoto() {
		return photo;
	}

	public void setPhoto(String photo) {
		this.photo = photo;
	}

	public String getRefCode() {
		return refCode;
	}

	public void setRefCode(String refCode) {
		this.refCode = refCode;
	}

	public String getRefName() {
		return refName;
	}

	public void setRefName(String refName) {
		this.refName = refName;
	}

	@JsonIgnore
	public String getPwdQuestion() {
		return pwdQuestion;
	}

	public void setPwdQuestion(String pwdQuestion) {
		this.pwdQuestion = pwdQuestion;
	}

	@JsonIgnore
	public String getPwdQuestionAnswer() {
		return pwdQuestionAnswer;
	}

	public void setPwdQuestionAnswer(String pwdQuestionAnswer) {
		this.pwdQuestionAnswer = pwdQuestionAnswer;
	}

	@JsonIgnore
	public String getPwdQuestion2() {
		return pwdQuestion2;
	}

	public void setPwdQuestion2(String pwdQuestion2) {
		this.pwdQuestion2 = pwdQuestion2;
	}

	@JsonIgnore
	public String getPwdQuestionAnswer2() {
		return pwdQuestionAnswer2;
	}

	public void setPwdQuestionAnswer2(String pwdQuestionAnswer2) {
		this.pwdQuestionAnswer2 = pwdQuestionAnswer2;
	}

	@JsonIgnore
	public String getPwdQuestion3() {
		return pwdQuestion3;
	}

	public void setPwdQuestion3(String pwdQuestion3) {
		this.pwdQuestion3 = pwdQuestion3;
	}

	@JsonIgnore
	public String getPwdQuestionAnswer3() {
		return pwdQuestionAnswer3;
	}

	public void setPwdQuestionAnswer3(String pwdQuestionAnswer3) {
		this.pwdQuestionAnswer3 = pwdQuestionAnswer3;
	}

	@JsonIgnore
	public Date getPwdModifyDate() {
		return pwdModifyDate;
	}

	public void setPwdModifyDate(Date pwdModifyDate) {
		this.pwdModifyDate = pwdModifyDate;
	}

	public String getMgrType() {
		return mgrType;
	}

	public void setMgrType(String mgrType) {
		this.mgrType = mgrType;
	}

	public Date getFreezeDate() {
		return freezeDate;
	}

	public void setFreezeDate(Date freezeDate) {
		this.freezeDate = freezeDate;
	}
	
	@ExcelField(title="备注", align=1, sort=900)
	public String getRemarks() {
		return super.getRemarks();
	}
	
	@Length(min=0, max=100, message="用户类型长度不能超过 100 个字符")
	@ExcelField(title="用户类型", align=2, sort=80, dictType="sys_user_type")
	public String getUserType() {
		return userType;
	}

	public void setUserType(String userType) {
		this.userType = userType;
	}

	@ExcelField(title="创建时间", type=0, align=1, sort=90)
	public Date getCreateDate() {
		return super.getCreateDate();
	}

	@ExcelField(title="最后登录IP", type=1, align=1, sort=100)
	public String getLoginIp() {
		return loginIp;
	}

	public void setLoginIp(String loginIp) {
		this.loginIp = loginIp;
	}

	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
	@ExcelField(title="最后登录日期", type=1, align=1, sort=110)
	public Date getLoginDate() {
		return loginDate;
	}

	public void setLoginDate(Date loginDate) {
		this.loginDate = loginDate;
	}
    
	public String getExtendS1() {
		return extendS1;
	}

	public void setExtendS1(String extendS1) {
		this.extendS1 = extendS1;
	}

	public String getExtendS2() {
		return extendS2;
	}

	public void setExtendS2(String extendS2) {
		this.extendS2 = extendS2;
	}

	public String getExtendS3() {
		return extendS3;
	}

	public void setExtendS3(String extendS3) {
		this.extendS3 = extendS3;
	}

	public String getExtendS4() {
		return extendS4;
	}

	public void setExtendS4(String extendS4) {
		this.extendS4 = extendS4;
	}

	public String getExtendS5() {
		return extendS5;
	}

	public void setExtendS5(String extendS5) {
		this.extendS5 = extendS5;
	}

	public Long getExtendI1() {
		return extendI1;
	}

	public void setExtendI1(Long extendI1) {
		this.extendI1 = extendI1;
	}

	public Long getExtendI2() {
		return extendI2;
	}

	public void setExtendI2(Long extendI2) {
		this.extendI2 = extendI2;
	}

	public Long getExtendI3() {
		return extendI3;
	}

	public void setExtendI3(Long extendI3) {
		this.extendI3 = extendI3;
	}

	public Float getExtendF1() {
		return extendF1;
	}

	public void setExtendF1(Float extendF1) {
		this.extendF1 = extendF1;
	}

	public Float getExtendF2() {
		return extendF2;
	}

	public void setExtendF2(Float extendF2) {
		this.extendF2 = extendF2;
	}

	public Float getExtendF3() {
		return extendF3;
	}

	public void setExtendF3(Float extendF3) {
		this.extendF3 = extendF3;
	}

	public Date getExtendD1() {
		return extendD1;
	}

	public void setExtendD1(Date extendD1) {
		this.extendD1 = extendD1;
	}

	public Date getExtendD2() {
		return extendD2;
	}

	public void setExtendD2(Date extendD2) {
		this.extendD2 = extendD2;
	}

	public Date getExtendD3() {
		return extendD3;
	}

	public void setExtendD3(Date extendD3) {
		this.extendD3 = extendD3;
	}
	
	/**
	 * 获取归属集团公司Code，取不到获取当前登录用户的集团公司Code
	 * @return
	 */
	public String getCorpCode_() {
		return corpCode;
	}

	/**
	 * 归属集团公司Name，取不到获取当前登录用户的集团公司Name
	 * @return
	 */
	public String getCorpName_() {
		return corpName;
	}

//	@JsonIgnore
//	public String getOldUserCode() {
//		return oldUserCode;
//	}
//
//	public void setOldUserCode(String oldUserCode) {
//		this.oldUserCode = oldUserCode;
//	}
//
//	@JsonIgnore
//	public String getNewPassword() {
//		return newPassword;
//	}
//
//	public void setNewPassword(String newPassword) {
//		this.newPassword = newPassword;
//	}
//
	public String getOldLoginIp() {
		if (oldLoginIp == null){
			return loginIp;
		}
		return oldLoginIp;
	}

	public void setOldLoginIp(String oldLoginIp) {
		this.oldLoginIp = oldLoginIp;
	}

	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
	public Date getOldLoginDate() {
		if (oldLoginDate == null){
			return loginDate;
		}
		return oldLoginDate;
	}

	public void setOldLoginDate(Date oldLoginDate) {
		this.oldLoginDate = oldLoginDate;
	}

	public String getRoleCode() {
		return roleCode;
	}

	public void setRoleCode(String roleCode) {
		this.roleCode = roleCode;
	}

	@JsonIgnore
	@ExcelField(title="拥有角色", align=1, sort=800, fieldType=RoleListType.class)
	public List<Role> getRoleList() {
		List<Role> l = Lists.newArrayList();
		if (roleList != null){
			for (Role r : roleList){
				// 不保存管理员角色，因为管理员角色是有系统内置的。
				if (!Role.isAdmin(r.getRoleCode())){
					l.add(r);
				}
			}
		}
		return l;
	}
	
	public void setRoleList(List<Role> roleList) {
		if(roleList != null && roleList.size()>0){
			List<String> codes = Lists.newArrayList();
			for(Role role : roleList){
				codes.add(role.getRoleCode());
			}
			this.roleCodes = StringUtils.join(codes.toArray(),',');
		}
		this.roleList = roleList;
	}

	/**
	 * 获取当前用户所拥有的角色Codes（前端用）
	 * @return
	 */
	public String getRoleCodes() {
		return roleCodes;
	}

	/**
	 * 设置当前用户所拥有的角色Codes（前端用）
	 */
	public void setRoleCodes(String roleCodes) {
		if(StringUtils.isNotBlank(roleCodes)) {
			this.roleList = Lists.newArrayList();
			for (String roleCode : StringUtils.split(roleCodes,',')) {
				Role role = new Role();
				role.setRoleCode(roleCode);
				roleList.add(role);
			}
		}
		this.roleCodes = roleCodes;
	}
	
	@JsonIgnore
	@ExcelField(title="拥有数据权限", align=1, sort=800, fieldType=UserDataScope.class)
	public List<UserDataScope> getUserDataScopeList() {
		return userDataScopeList;
	}
	
	/**
	 * 用来保存当前用户，所拥有的数据权限范围的数据信息（包括公司和部门）
	 * @param userDataScopeList
	 */
	public void setUserDataScopeList(List<UserDataScope> userDataScopeList) {
		if(userDataScopeList != null && userDataScopeList.size() > 0){
			List<String> companyCodes = Lists.newArrayList();
			List<String> officeCodes = Lists.newArrayList();
			for(UserDataScope userDataScope : userDataScopeList){
				if(userDataScope.getCtrlType().equals(UserDataScope.CTRL_TYPE_COMPANY)){
					companyCodes.add(userDataScope.getCtrlData());
				}else if(userDataScope.getCtrlType().equals(UserDataScope.CTRL_TYPE_OFFICE)){
					officeCodes.add(userDataScope.getCtrlData());
				}
			}
			this.companyCodes = StringUtils.join(companyCodes.toArray() , ',');
			this.officeCodes = StringUtils.join(officeCodes.toArray() , ',');
		}
		this.userDataScopeList = userDataScopeList;
	}
	
	/**
	 * 获取当前用户所拥有数据权限的公司Codes（前端用）
	 */
	public String getCompanyCodes() {
		return companyCodes;
	}

	/**
	 * 设置当前用户所拥有数据权限的公司Codes（前端用）
	 */
	public void setCompanyCodes(String companyCodes) {
		if(StringUtils.isNotBlank(companyCodes)) {
			String[] codes = StringUtils.split(companyCodes, ",");
			for (String companyCode : codes) {
				UserDataScope userDataScope = new UserDataScope();
				userDataScope.setUserCode(this.userCode);
				userDataScope.setCtrlType(UserDataScope.CTRL_TYPE_COMPANY);
				userDataScope.setCtrlData(companyCode);
				this.userDataScopeList.add(userDataScope);
			}
		}
		this.companyCodes = companyCodes;
	}

	/**
	 * 获取当前用户所拥有数据权限的部门Codes（前端用）
	 */
	public String getOfficeCodes() {
		return officeCodes;
	}

	/**
	 * 设置当前用户所拥有数据权限的部门Codes（前端用）
	 */
	public void setOfficeCodes(String officeCodes) {
		if(StringUtils.isNotBlank(officeCodes)) {
			String[] codes = StringUtils.split(officeCodes, ",");
			for (String officeCode : codes) {
				UserDataScope userDataScope = new UserDataScope();
				userDataScope.setUserCode(this.userCode);
				userDataScope.setCtrlType(UserDataScope.CTRL_TYPE_OFFICE);
				userDataScope.setCtrlData(officeCode);
				this.userDataScopeList.add(userDataScope);
			}
		}
		this.officeCodes = officeCodes;
	}

	/**
	 * 对应引用类型详细信息
	 * @return
	 */
	public Object getRefObj() {
		if (refObj == null && employee != null){
			refObj = employee;
		}
		return refObj;
	}

	public void setRefObj(Object refObj) {
		this.refObj = refObj;
	}

	@JsonIgnore
	public Employee getEmployee() {
		if (employee == null){
			if (refObj != null){
				employee = (Employee)refObj;
			}else{
				employee = new Employee();
			}
		}
		return employee;
	}

	public void setEmployee(Employee employee) {
		this.employee = employee;
	}
	
	/**
	 * 获取DWR脚本SessionId
	 * @return
	 */
	@JsonIgnore
	@Deprecated
	public List<String> getScriptSessionIds() {
		return scriptSessionIds;
	}
	
	/**
	 * 是否查询所有用户
	 * @return
	 */
	public boolean isAll() {
		return BooleanUtils.toBoolean(isAll);
	}

	public void setAll(boolean isAll) {
		this.isAll = isAll;
	}

	public void setIsAll(String isAll) {
		this.isAll = Global.TRUE.equals(isAll);
	}
	
	/**
	 * 重写toString方法，返回loginName
	 */
	@Override
	public String toString() {
		return userCode;
	}

	/**
	 * 是否是超级或系统管理员
	 * @return
	 */
	@JsonIgnore
	public boolean isAdmin(){
		return isAdmin(this.userCode);
	}

	/**
	 * 判断userCode是否是超级或系统管理员
	 * @return
	 */
	public static boolean isAdmin(String userCode){
		return isSuperAdmin(userCode) || isSystemAdmin(userCode);
	}

	/**
	 * 是否是超级管理员
	 * @return
	 */
	@JsonIgnore
	public boolean isSuperAdmin(){
		return isSuperAdmin(this.userCode);
	}

	/**
	 * 判断userCode是否是超级管理员
	 * @return
	 */
	public static boolean isSuperAdmin(String userCode){
		return userCode != null && StringUtils.inString(userCode, SUPER_ADMIN_CODE.split(","));
	}

	/**
	 * 是否是超级管理员（与超级管理员的区别：系统管理员是给客户用的（有限定权限的，但不受数据权限控制）；超级管理员是给开发或实施用的包括全部权限。）
	 * @return
	 */
	@JsonIgnore
	public boolean isSystemAdmin(){
		return isSystemAdmin(this.userCode);
	}

	/**
	 * 判断userCode是否是系统管理员（与超级管理员的区别：系统管理员是给客户用的（有限定权限的，但不受数据权限控制）；超级管理员是给开发或实施用的包括全部权限。）
	 * @return
	 */
	public static boolean isSystemAdmin(String userCode){
		return userCode != null && StringUtils.inString(userCode, SYSTEM_ADMIN_CODE.split(","));
	}

	public String getOfficeCode() {
		return officeCode;
	}

	public void setOfficeCode(String officeCode) {
		this.officeCode = officeCode;
	}

	public String getOfficeName() {
		return officeName;
	}

	public void setOfficeName(String officeName) {
		this.officeName = officeName;
	}

	/**
	 * 超级管理员编号
	 */
	public static final String SUPER_ADMIN_CODE = Global.getConfig("user.superAdminCode");
	
	/**
	 * 系统管理员编号（与超级管理员的区别：系统管理员是给客户用的（有限定权限的，但不受数据权限控制）；超级管理员是给开发或实施用的包括全部权限。）
	 */
	public static final String SYSTEM_ADMIN_CODE = Global.getConfig("user.systemAdminCode");

	/**
	 * 管理员类型（0：普通用户）
	 */
	public static final String MGR_TYPE_NOT_ADMIN = "0";
	
	/**
	 * 管理员类型（1：二级管理员）
	 */
	public static final String MGR_TYPE_SEC_ADMIN = "1";
	
	/**
	 * 管理员类型（2：集团管理员）
	 */
	public static final String MGR_TYPE_CORP_ADMIN = "2";

	/**
	 * 用户类型（1：仅登录）
	 */
	public static final String USER_TYPE_ONLYLOGIN = "0";
	
	/**
	 * 用户类型（1：员工）
	 */
	public static final String USER_TYPE_EMPLOYEE = "1";
	
	/**
	 * 用户类型（2：会员）
	 */
	public static final String USER_TYPE_MEMBER = "2";
	
	/**
	 * 用户类型（3：往来单位）
	 */
	public static final String USER_TYPE_BTYPE = "3";

	/**
	 * 用户类型（4：个人）
	 */
	public static final String USER_TYPE_PERSION = "4";
	
	/**
	 * 用户类型（4：个人）
	 * @deprecated #USER_TYPE_PERSION
	 */
	public static final String USER_PERSION = USER_TYPE_PERSION;

	/**
	 * 用户类型（5：专家）
	 */
	public static final String USER_TYPE_EXPERT = "5";

	/**
	 * 用户类型（5：专家）
	 * @deprecated #USER_TYPE_EXPERT
	 */
	public static final String USER_EXPERT = USER_TYPE_EXPERT;

}